package com.baofu.paycore.biz.task;

import com.baofu.paycore.biz.paycore.handler.impl.WithdrawHandler;
import com.baofu.paycore.biz.tools.BuildModel;
import com.baofu.paycore.common.constant.PayCoreConstant;
import com.baofu.paycore.common.enums.BizCmdTypeEnum;
import com.baofu.paycore.common.enums.RedisKeyEnum;
import com.baofu.paycore.manager.cache.RedisLockManager;
import com.baofu.paycore.service.facade.enums.ServiceCodeEnum;
import com.baofu.paycore.common.exception.PayCoreBizException;
import com.baofu.paycore.service.facade.enums.PayCoreErrorCode;
import com.baofu.paycore.dal.model.ErrorLogDO;
import com.baofu.paycore.manager.model.withdraw.WithdrawBO;
import com.baofu.paycore.manager.storage.impl.ErrorLogManager;
import com.baofu.paycore.manager.storer.WithdrawOrderRepository;
import com.google.common.base.Splitter;
import com.system.commons.exception.BizServiceException;
import com.system.dispatch.dal.model.BizCmdDO;
import com.system.dispatch.impl.BaseCmdHandler;
import lombok.extern.slf4j.Slf4j;
import org.jboss.logging.MDC;
import org.slf4j.helpers.SystemMarker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 账务解冻dispatch
 *
 * <p>
 *  1.获得执行任务名称
 *  2.执行任务
 *  3.任务执行最后失败信息
 * </p>
 * User: xin deng  Date: 16/7/6 ProjectName: paycore Version: 1.0
 */
@Slf4j
@Component
public class AccUnFreezeDispatch extends BaseCmdHandler {

    /**
     * 提现
     */
    @Autowired
    private WithdrawOrderRepository withdrawOrderRepository;

    /**
     * 提现解冻处理
     */
    @Autowired
    private WithdrawHandler withdrawHandler;

    /**
     * 差错日志管理
     */
    @Autowired
    private ErrorLogManager errorLogManager;

    /**
     * 锁服务
     */
    @Autowired
    private RedisLockManager redisLockManager;

    /**
     * 2.执行任务
     *
     * @param command 任务
     * @throws Exception 异常
     */
    @Override
    protected void doCmd(BizCmdDO command) throws Exception {

        MDC.put(SystemMarker.TRACE_LOG_ID, command.getTraceLogId());
        if (StringUtils.isEmpty(command.getBizId())){
            log.error("账务解冻任务执行Dispatch异常 command:{}", command);
            return;
        }
        long startTime = System.currentTimeMillis();
        String requestType = null;
        String payNo = null;
        try {
            List<String> strings = Splitter.on(PayCoreConstant.BASE_CMD_SEPARATOR).splitToList(command.getBizId());
            requestType = strings.get(0);
            payNo = strings.get(1);
            log.info("账务解冻任务开始 请求服务类型:{} 支付单号:{}", requestType, payNo);
            ServiceCodeEnum serviceCode = ServiceCodeEnum.explain(requestType);
            if(null == serviceCode){
                log.error("账务解冻 支付类型有误 serviceCode:{}", requestType);
                throw new BizServiceException(PayCoreErrorCode.PAY_TYPE_NOT_EXISTED);
            }
            switch (serviceCode){
                case WITHDRAW:
                    this.withdraw(payNo);
                    break;
                default:
                    log.error("暂不支持此业务：{}", serviceCode);
                    throw new PayCoreBizException(PayCoreErrorCode.NOT_IN_SERVICE);
            }

        }catch (Exception e){
            log.error("执行账务解冻任务异常 请求类型:{} 请求单号:{} 失败:{}", requestType, payNo, e);
            throw e;
        }finally {
            log.info("账务解冻任务结束 请求服务类型:{} 支付单号:{} 耗时:{}ms", requestType, payNo,
                    System.currentTimeMillis() - startTime);
        }
    }


    /**
     * 3.任务执行最后失败信息
     *
     * @param command 任务
     */
    @Override
    protected void failedFinally(BizCmdDO command) {
        log.error("账务解冻处理 bizId:{},{}", command.getBizId(), command.getTraceLogId());
        List<String> strings = Splitter.on(PayCoreConstant.BASE_CMD_SEPARATOR).splitToList(command.getBizId());
        String requestType = strings.get(0);
        String payNo = strings.get(1);
        ErrorLogDO errorLogDO = BuildModel.buildErrorLog(payNo, null, BizCmdTypeEnum.ACC_UNFREEZE.getCode(),
                requestType, PayCoreErrorCode.ACC_UNFREEZE_EXCEPTION.getErrorCode(),
                command.getFailReason(), "账务解冻dispatch失败");
        errorLogManager.addOrder(errorLogDO);
    }

    /**
     * 提现处理
     *
     * @param payNo 支付单号
     */
    private void withdraw(String payNo) {
        boolean flag=false;
        try{
            flag = redisLockManager.lock(RedisKeyEnum.PAY_ACC_UNFREEZE, payNo);
            WithdrawBO withdrawBO = withdrawOrderRepository.loadOrderByPayNo(payNo);
            withdrawHandler.withdrawUnFreeze(withdrawBO);
        }catch (Exception e){
            log.error("提现出现异常!",e);
        }finally {
            if(flag) {
                redisLockManager.release(RedisKeyEnum.PAY_ACC_UNFREEZE, payNo);
            }
        }
    }
}
